package org.csu.validator;

import java.util.HashMap;
import java.util.Map;

/**
 * 通用数据验证结果封装类
 * 作用：统一收集、管理各类数据校验的错误信息（如参数校验、业务规则校验）
 * 核心价值：
 * 1. 集中存储多个校验错误（避免单次校验只返回一个错误，提升用户体验）
 * 2. 提供明确的"是否通过验证"标识，简化Controller层判断逻辑
 * 3. 支持错误信息拼接，方便前端直接展示或日志记录
 * 适用场景：图书新增/修改时的ISBN格式校验、库存合理性校验、必填字段校验等
 */
public class ValidationResult {
    /**
     * 验证结果标识：true=存在错误（验证未通过），false=无错误（验证通过）
     * 无需手动设置：调用addError()添加错误时会自动设为true；无错误时默认false
     */
    private boolean hasErrors;

    /**
     * 错误信息存储集合：key=校验失败的字段名（如"isbn"、"stock"、"bookName"），value=对应错误提示
     * 示例：{"isbn": "ISBN格式错误，需为10位或13位数字", "stock": "库存数量不能为负数"}
     */
    private Map<String, String> errorMsgMap = new HashMap<String, String>();

    // ==========  getter/setter 方法（用于获取/修改校验结果信息） ==========
    /**
     * 获取验证结果标识
     * @return true=验证未通过（存在错误），false=验证通过（无错误）
     */
    public boolean isHasErrors() {
        return hasErrors;
    }

    /**
     * 设置验证结果标识（一般无需手动调用，addError()会自动维护）
     * @param hasErrors 验证结果标识
     */
    public void setHasErrors(boolean hasErrors) {
        this.hasErrors = hasErrors;
    }

    /**
     * 获取所有错误信息的集合
     * @return Map<字段名, 错误提示>，可用于前端针对性展示字段错误（如表单字段下方显示对应错误）
     */
    public Map<String, String> getErrorMsgMap() {
        return errorMsgMap;
    }

    /**
     * 设置错误信息集合（一般用于批量导入错误，日常单个错误推荐用addError()）
     * @param errorMsgMap 错误信息集合
     */
    public void setErrorMsgMap(Map<String, String> errorMsgMap) {
        this.errorMsgMap = errorMsgMap;
        // 若设置的错误集合非空，自动标记为"存在错误"
        this.hasErrors = errorMsgMap != null && !errorMsgMap.isEmpty();
    }

    // ==========  错误信息操作工具方法（核心常用） ==========
    /**
     * 添加单个字段的错误信息
     * @param field 校验失败的字段名（需与实体类字段/前端表单字段一致，如"isbn"、"bookName"）
     * @param message 错误提示信息（前端可直接展示给用户，如"图书名称不能为空"）
     */
    public void addError(String field, String message) {
        this.errorMsgMap.put(field, message); // 存入错误集合
        this.hasErrors = true; // 只要添加错误，自动标记为"验证未通过"
    }

    /**
     * 获取拼接后的完整错误信息（多个错误用"；"分隔）
     * @return 拼接后的错误字符串，示例："ISBN格式错误；库存不能为负数；图书名称不能为空"
     * 适用场景：前端弹窗提示、日志记录、接口统一错误返回
     */
    public String getErrorMsg() {
        StringBuilder sb = new StringBuilder();
        for (String msg : errorMsgMap.values()) {
            if (sb.length() > 0) {
                sb.append("；"); // 多个错误用中文分号分隔，提升可读性
            }
            sb.append(msg);
        }
        return sb.toString();
    }
}